package navsrvlogic

import (
	"context"
	"math"
	"strconv"
	"strings"

	"gozero-microservices/common-service/rpc/internal/model"
	"gozero-microservices/common-service/rpc/internal/svc"
	"gozero-microservices/common-service/rpc/types/common"
	"gozero-microservices/common-service/rpc/utils"

	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type NavLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

/**
 * 创建导航逻辑实例
 *
 * @param context.Context ctx ----------------------必传
 * @param *svc.ServiceContext svcCtx ---------------必传
 * @return *NavLogic
 * @author huwl
 * @date 2025/10/14 12:54:03
 */
func NewNavLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *NavLogic {
	return &NavLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

/**
 * 新增
 *
 * @param string Title ------------------------必传,标题
 * @param string Link -------------------------非必传,链接
 * @param uint32 Position ---------------------非必传,位置
 * @param uint32 IsOpenNew --------------------非必传,是否打开新页面
 * @param uint32 RelationGoods ----------------非必传,排序关联商品
 * @param uint32 Sort -------------------------非必传,排序
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) AddNav(in *common.AddNavRequest) (*common.Result, error) {
	if in.Title == "" {
		return nil, status.Errorf(codes.InvalidArgument, "标题不能为空")
	}

	// 操作数据库
	_, err := l.svcCtx.NavModel.Insert(l.ctx, &model.MallNav{})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "新增导航成功",
	}, nil
}

/**
 * 删除
 *
 * @param string Ids --------------------------必传,Id支持多个
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) DeleteNav(in *common.DeleteRequest) (*common.Result, error) {
	if in.Ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	err := l.svcCtx.NavModel.EditByParams(l.ctx, map[string]interface{}{
		"status": -2,
	}, map[string]interface{}{
		"id IN (?)": utils.IntSplit(strings.TrimRight(in.Ids, ","), ","),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "删除导航成功",
	}, nil
}

/**
 * 编辑
 *
 * @param string Id ---------------------------必传,Id
 * @param string Title ------------------------非必传,标题
 * @param string Link--------------------------非必传,链接
 * @param uint32 Position ---------------------非必传,位置
 * @param uint32 IsOpenNew --------------------非必传,是否打开新页面
 * @param string RelationGoods ----------------非必传,关联商品
 * @param uint32 Sort -------------------------非必传,排序
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) EditNav(in *common.EditNavRequest) (*common.Result, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	params := map[string]interface{}{}
	if in.Title != "" {
		params["title"] = in.Title
	}
	if in.Link != "" {
		params["link"] = in.Link
	}
	if in.Position > 0 {
		params["position"] = in.Position
	}
	if in.IsOpenNew != "all" {
		isOpenNew, _ := strconv.Atoi(in.IsOpenNew)
		params["is_open_new"] = isOpenNew
	}
	if in.RelationGoods != "all" {
		params["relation_goods"] = in.RelationGoods
	}
	if in.Sort > 0 {
		params["sort"] = in.Sort
	}

	err := l.svcCtx.NavModel.EditByPrimaryKey(l.ctx, params, in.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "编辑导航成功",
	}, nil
}

/**
 * 编辑状态
 *
 * @param string Ids --------------------------必传,Id支持多个
 * @param int32 Status ------------------------非必传,状态
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) EditStatusNav(in *common.EditStatusRequest) (*common.Result, error) {
	ids := strings.TrimRight(in.Ids, ",")
	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}
	if !utils.IsContainNumber[int8]([]int8{-1, 1}, int8(in.Status)) {
		return nil, status.Errorf(codes.InvalidArgument, "状态错误")
	}

	// 操作数据库
	err := l.svcCtx.NavModel.EditByParams(l.ctx, map[string]interface{}{
		"status": in.Status,
	}, map[string]interface{}{
		"id IN (?)": utils.IntSplit(ids, ","),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	message := ""
	if in.Status == 1 {
		message = "启用"
	} else {
		message = "禁用"
	}

	return &common.Result{
		Code: 200,
		Msg:  message + "导航成功",
	}, nil
}

/**
 * 详情
 *
 * @param uint64 Id ---------------------------必传,Id
 * @return *common.Nav, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) NavDetail(in *common.DetailRequest) (*common.Nav, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	// 操作数据库
	navRes, err := l.svcCtx.NavModel.FindOne(l.ctx, int64(in.Id))
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, status.Errorf(codes.Aborted, "导航信息错误")
		}

		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if navRes.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "导航信息错误")
	}

	// 组装数据
	return &common.Nav{
		Id:            uint32(navRes.Id),
		Title:         navRes.Title,
		Link:          navRes.Link,
		Position:      uint32(navRes.Position),
		IsOpenNew:     uint32(navRes.IsOpenNew),
		RelationGoods: navRes.RelationGoods,
		Sort:          uint32(navRes.Sort),
		Status:        int32(navRes.Status),
		CreateTime:    navRes.CreateTime.Time.String(),
		UpdateTime:    navRes.UpdateTime.Time.String(),
	}, nil
}

/**
 * 列表
 *
 * @param uint32 Id ---------------------------非必传,Id
 * @param string Ids --------------------------非必传,Id支持多个
 * @param string Title ------------------------非必传,标题
 * @param uint32 Position ---------------------非必传,位置
 * @param string IsOpenNew --------------------非必传,是否打开新页面
 * @param string Status -----------------------非必传,状态
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @param string SortField --------------------非必传,排序字段
 * @param string SortType ---------------------非必传,排序方式
 * @param int32 PageSize ----------------------非必传,条数
 * @param uint32 Page -------------------------非必传,页码
 * @return *common.BannerListResult, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) NavList(in *common.QueryNavRequest) (*common.NavListResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := in.Page
	pageSize := in.PageSize
	sortType := in.SortType
	sortField := in.SortField

	if in.Id > 0 {
		params["id"] = in.Id
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Title != "" {
		params["title"] = in.Title
	}
	if in.Position > 0 {
		params["position"] = in.Position
	}
	if in.IsOpenNew != "all" {
		params["is_open_new"] = in.IsOpenNew
	}
	if in.Status != "all" {
		params["status IN (?)"] = utils.IntSplit(in.Status, ",")
	}
	if in.StartCreateTime != "" {
		params["create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "id"
	}
	if sortType == "" {
		sortType = "desc"
	}

	// 查询数量
	total, err := l.svcCtx.NavModel.GetResultsByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	var navs []*model.MallNav
	if total > 0 {
		err = l.svcCtx.NavModel.GetResultsByParams(l.ctx, &navs, params, page, int8(pageSize), sortField+" "+sortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
	}

	// 组装数据
	navItems := []*common.Nav{}
	for _, nav := range navs {
		navItems = append(navItems, &common.Nav{
			Id:            uint32(nav.Id),
			Title:         nav.Title,
			Link:          nav.Link,
			Position:      uint32(nav.Position),
			IsOpenNew:     uint32(nav.IsOpenNew),
			RelationGoods: nav.RelationGoods,
			Sort:          uint32(nav.Sort),
			Status:        int32(nav.Status),
			CreateTime:    nav.CreateTime.Time.String(),
			UpdateTime:    nav.UpdateTime.Time.String(),
		})
	}

	// 计算总页数
	pageTotal := math.Ceil(float64(total) / float64(pageSize))

	return &common.NavListResult{
		Page:      page,
		PageSize:  pageSize,
		Total:     int32(total),
		PageTotal: int32(pageTotal),
		Navs:      navItems,
	}, nil
}

/**
 * 数量
 *
 * @param uint32 Id ---------------------------非必传,Id
 * @param string Ids --------------------------非必传,Id支持多个
 * @param string Title ------------------------非必传,标题
 * @param uint32 Position ---------------------非必传,位置
 * @param string IsOpenNew --------------------非必传,是否打开新页面
 * @param string Status -----------------------非必传,状态
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @return *common.TotalResult, error
 * @author huwl
 * @date 2025/10/23 10:12:43
 */
func (l *NavLogic) NavTotal(in *common.QueryNavRequest) (*common.TotalResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	if in.Id > 0 {
		params["id"] = in.Id
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Title != "" {
		params["title"] = in.Title
	}
	if in.Position > 0 {
		params["position"] = in.Position
	}
	if in.IsOpenNew != "all" {
		params["is_open_new"] = in.IsOpenNew
	}
	if in.Status != "all" {
		params["status IN (?)"] = utils.IntSplit(in.Status, ",")
	}
	if in.StartCreateTime != "" {
		params["create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}

	// 查询数量
	total, err := l.svcCtx.NavModel.GetResultsByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.TotalResult{
		Total: uint32(total),
	}, nil
}
